package com.zhoug.map3demo;

import android.Manifest;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PointF;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.zhoug.common3.http.SchedulerUtils;
import com.zhoug.common3.json.GsonUtils;
import com.zhoug.common3.permission.ZPermissions;
import com.zhoug.common3.utils.LogUtils;
import com.zhoug.common3.utils.ToastUtils;
import com.zhoug.map3.AreaBoundary;
import com.zhoug.map3.Callback;
import com.zhoug.map3.DouglasPeucker;
import com.zhoug.map3.MapBound;
import com.zhoug.map3.MapHelper;
import com.zhoug.map3.MarkerManager;
import com.zhoug.map3.MyMarker;
import com.zhoug.map3.OnClickMapListener;
import com.zhoug.map3.OsmdroidUtils;
import com.zhoug.map3.PolygonMask;
import com.zhoug.map3.PolygonMaskManager;
import com.zhoug.map3.Utils;
import com.zhoug.map3.dianditu.Poi;
import com.zhoug.map3.dianditu.SearchParams;
import com.zhoug.map3.dianditu.SearchResult;
import com.zhoug.map3.dianditu.TianDiTuApi;
import com.zhoug.map3.dianditu.TianTileSource;
import com.zhoug.map3.location.GpsLocationService;
import com.zhoug.map3.location.GpsSettingHelper;
import com.zhoug.map3.location.LocationService;
import com.zhoug.map3.location.OnGpsChangeListener;
import com.zhoug.map3.location.ZAddress;
import com.zhoug.map3.location.ZLatLng;
import com.zhoug.map3.location.ZLocation;

import org.osmdroid.api.IGeoPoint;
import org.osmdroid.api.IMapController;
import org.osmdroid.events.DelayedMapListener;
import org.osmdroid.events.MapListener;
import org.osmdroid.events.ScrollEvent;
import org.osmdroid.events.ZoomEvent;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.Marker;
import org.osmdroid.views.overlay.Overlay;
import org.osmdroid.views.overlay.OverlayManager;
import org.osmdroid.views.overlay.Polyline;
import org.osmdroid.views.overlay.infowindow.InfoWindow;

import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import androidx.core.content.ContextCompat;
import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.disposables.Disposable;

public class MainActivity extends MyBaseActivity {
    private static final String MAP_KEY = "6403b61c87ad844c9279edffa365bc42";//周淦
    //        private static final String MAP_KEY = "81855087c4c257f7edb24acb8a6de3f2";//周滔
//    private static final String MAP_KEY = "48ff5138e7b8f8f23620cbca790a82fe";//公司
    private MarkerManager mMarkerManager;
    private InfoWindow mShowInfoWindow;
    private int mAreaIndex = -1;
    private PolygonMaskManager mPolygonMaskManager;
    private GpsLocationService mGpsLocationService;
    private GpsSettingHelper mGpsSettingHelper;
    private MapView mMapView;
    private MapHelper mMapHelper;
    private Button mBtnLocation;
    private Button mBtnMarker;
    private Button mBtnMarkerRemove;
    private ProgressBar mProgress;
    private Button mBtnSearchArea;
    private Button mBtnSearchBound;
    private Button mBtnSearchNear;
    private Button mBtnGeocoder;
    private Button mBtnGeocoder2;
    private Button mBtnGetArea;
    private Button mBtnPolyline;
    private Button mBtnPolygon;
    private Button mBtnSearchNormal;

    @Override
    protected int getLayoutResId() {
        return R.layout.activity_main;
    }

    @Override
    protected void findViews() {

        mMapView = findViewById(R.id.mapView);
        mBtnLocation = findViewById(R.id.btn_location);
        mBtnMarker = findViewById(R.id.btn_marker);
        mBtnMarkerRemove = findViewById(R.id.btn_markerRemove);
        mProgress = findViewById(R.id.progress);
        mBtnSearchArea = findViewById(R.id.btn_search_area);
        mBtnSearchBound = findViewById(R.id.btn_search_bound);
        mBtnSearchNear = findViewById(R.id.btn_search_near);
        mBtnGeocoder = findViewById(R.id.btn_geocoder);
        mBtnGeocoder2 = findViewById(R.id.btn_geocoder2);
        mBtnGetArea = findViewById(R.id.btn_getArea);
        mBtnPolyline = findViewById(R.id.btn_polyline);
        mBtnPolygon = findViewById(R.id.btn_polygon);
        mBtnSearchNormal = findViewById(R.id.btn_search_normal);
    }

    private void startLocation() {
        LogUtils.d(TAG, "startLocation:开始定位");
        mGpsLocationService.start();
    }

    @Override
    protected void onCreate1(Bundle savedInstanceState) {
        ZPermissions.with(this)
                .setPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        Manifest.permission.READ_EXTERNAL_STORAGE)
                .setCallback((success, granted, denied) -> {

                })
                .request();

        TianDiTuApi.setMapKey(MAP_KEY);
        //天地图新版
        // 矢量底图
//        mMapView.setTileSource(new TianDiTuTileSourceFactory(MAP_KEY).getTileSource());
        //矢量注记
//        TilesOverlay tilesOverlay = new TilesOverlay(new MapTileProviderBasic(this, new TianDiTuTileSourceFactory(TianDiTuTileSourceFactory.CVA_W, MAP_KEY).getTileSource()), this);
//        mMapView.getOverlayManager().add(tilesOverlay);
        //天地图旧版
        mMapView.setTileSource(new TianTileSource(MAP_KEY));
        //天地图自己服务器
//        mMapView.setTileSource(new TianDiTuLocalHostSource());
        mMapHelper = new MapHelper(this, mMapView);
//        String externalFolder = FileUtils.getExternalFolder("1");
//        File tiandituZip=null;
//        if(externalFolder!=null){
//            tiandituZip=new File(externalFolder,"0map/tianditu.zip");
//        }
//        LogUtils.d(TAG, "tiandituZip:"+(tiandituZip!=null?tiandituZip.getAbsolutePath():null));
//        mMapHelper.setOfflineTileSourcePath(tiandituZip);
        mMapHelper.setLifecycleOwner(this);
        mMapHelper.setDefConfig();
        mMapHelper.setOnClickMapListener(new OnClickMapListener() {
            @Override
            public boolean onClickMap(ZLatLng latLng, PointF point) {
                LogUtils.d(TAG, "onClickMap:latLng="+GsonUtils.getDefault().toJson(latLng));
                LogUtils.d(TAG, "onClickMap:point="+GsonUtils.getDefault().toJson(point));
                if(latLng!=null){
                    Marker marker=new Marker(mMapView);
                    marker.setPosition(new GeoPoint(latLng.getLatitude(),latLng.getLongitude()));
                    marker.setIcon(ContextCompat.getDrawable(getActivity(),R.drawable.icon_map_monitor_online));
                    marker.setAnchor(.5f,1.0f);
                    marker.setInfoWindow(null);
                    mMapView.getOverlays().add(marker);
                    mMapView.postInvalidate();
                }


                return true;
            }
        });
        mMarkerManager = new MarkerManager(mMapView);
        mPolygonMaskManager = new PolygonMaskManager(mMapView);
        mPolygonMaskManager.setIsAnimated(false);
        mMapHelper.setScrollLimitChinaBound();
       /* mMapView.addMapListener(new MapListener() {
            @Override
            public boolean onScroll(ScrollEvent event) {
                LogUtils.d(TAG, "onScroll:" + GsonUtils.getDefault().toJson(mMapHelper.getMapBound()));
                return false;
            }

            @Override
            public boolean onZoom(ZoomEvent event) {
                LogUtils.d(TAG, "onZoom:" + event.getZoomLevel());
                return false;
            }
        });*/

        mMapView.addMapListener(new DelayedMapListener(new MapListener() {
            @Override
            public boolean onScroll(ScrollEvent event) {
                LogUtils.d(TAG, "onScroll:" + event.getX() + "," + event.getY());
                boolean touchMap = mMapHelper.isTouchMap();
                LogUtils.d(TAG, "touchMap:" + touchMap);
                if (!touchMap) {
//                    loadFirms();
                }
                return false;
            }

            @Override
            public boolean onZoom(ZoomEvent event) {
                LogUtils.d(TAG, "onZoom:" + event.getZoomLevel());
                boolean touchMap = mMapHelper.isTouchMap();
                LogUtils.d(TAG, "touchMap:" + touchMap);
                if (!touchMap) {
//                    loadFirms();
                }
                return false;
            }
        }, 500));
//        mMapHelper.addScaleBarOverlay();
//        mMapHelper.addCompassOverlay();
//        mMapHelper.addRotationGestureOverlay();
//        mMapHelper.addMinimapOverlay();
        OverlayManager overlayManager = mMapView.getOverlayManager();
        //点击事件
        overlayManager.add(new Overlay() {

            @Override
            public boolean onSingleTapConfirmed(MotionEvent e, MapView mapView) {
                LogUtils.d(TAG, "onSingleTapConfirmed:x=" + e.getX() + ",y=" + e.getY());
                return super.onSingleTapConfirmed(e, mapView);
            }
        });
        mGpsSettingHelper = new GpsSettingHelper(this);
        mGpsSettingHelper.setOnGpsChangeListener(new OnGpsChangeListener() {
            @Override
            public void onGpsChange(boolean isGpsOpen) {
                if (isGpsOpen) {
                    startLocation();
                }
            }
        });

        mGpsLocationService = new GpsLocationService(getApplication());
        mGpsLocationService.setListenerProviderStatus(true);
        mGpsLocationService.setAddressEnable(true);
        mGpsLocationService.setGeocoderType(LocationService.GEOCODER_TYPE_TIANDITU);
        mGpsLocationService.addOnLocationListener(location -> {
            LogUtils.d(TAG, "onReceiveLocation:" + location);
            toast(GsonUtils.getDefault().toJson(location));
            GeoPoint myLocation = new GeoPoint(location.getLatitude(), location.getLongitude());
            mMapHelper.setMyLocation(myLocation);
            mMapHelper.animateTo(myLocation);
//            mGpsLocationService.stop();
        });

        ZLocation lastLocation = mGpsLocationService.getLastLocation();
        LogUtils.d(TAG, "lastLocation:" + lastLocation);
        mBtnLocation.setOnClickListener(v -> {
            ZPermissions.with(this)
                    .setPermissions(Manifest.permission.ACCESS_FINE_LOCATION,
                            Manifest.permission.ACCESS_COARSE_LOCATION)
                    .setCallback((success, granted, denied) -> {
                        if (success) {
//                            if (mGpsSettingHelper.isGpsOpen()) {
//                                startLocation();
//                            } else {
//                                mGpsSettingHelper.toGpsSetting();
//                            }
                            startLocation();
                        }

                    })
                    .request();

        });

        //29.20332016007599,106.11328125
//        Marker marker = new Marker(mMapView);
//        marker.setAnchor(0.5f, 0.5f);
//        marker.setIcon(ContextCompat.getDrawable(this, R.drawable.icon_map_monitor_null));
//        marker.setPosition(new GeoPoint(29.204, 106.12));
//        mMapHelper.addMarker(marker);

        mBtnMarker.setOnClickListener(v -> {
            loadFirms();
        });

        mBtnMarkerRemove.setOnClickListener(v -> {
            mMapHelper.removeAllMarkers(false);
            //            mMarkerManager.removeMarkers();
            mPolygonMaskManager.clear();
            mMapHelper.setScrollLimitChinaBound();
            mMapView.setMinZoomLevel(3.0);
            mMapView.setZoomLevel(3.0);
            mMapView.postInvalidate();
        });
        //行政区划区域搜索服务
        mBtnSearchArea.setOnClickListener(v -> {
            search(SearchParams.QUERY_TYPE_AREA);
        });
        //视野内搜索
        mBtnSearchBound.setOnClickListener(v -> {
            search(SearchParams.QUERY_TYPE_BOUND);
        });
        //周边搜索
        mBtnSearchNear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                search(SearchParams.QUERY_TYPE_NEAR);
            }
        });
        //普通搜索
        mBtnSearchNormal.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                search(SearchParams.QUERY_TYPE_NORMAL);
            }
        });


        //地理编码
        mBtnGeocoder.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showLoading();
                TianDiTuApi tianDiTuApi = TianDiTuApi.getInstance();
                final String keyWord = "重庆市渝北区西南政法大学";
                tianDiTuApi.geocoder(keyWord,  new Callback<ZLatLng>() {
                    @Override
                    public void onSuccess(ZLatLng data) {
                        hideLoading();
                        if (data != null) {
                            List<Marker> markers = new ArrayList<>();
                            MyMarker marker = new MyMarker(mMapView);
                            marker.setIcon(ContextCompat.getDrawable(getActivity(), R.drawable.icon_map_monitor_online));
                            marker.setAnchor(0, 0.5f);
                            marker.setPosition(new GeoPoint(data.getLatitude(), data.getLongitude()));
                            marker.setId(keyWord);
                            marker.setRelatedObject(data);
                            marker.setInfoWindow(null);
                            if (mMapView.getZoomLevelDouble() < 13) {
                                mMapView.setZoomLevel(13);
                            }
                            mMapHelper.animateTo(marker.getPosition());
                            markers.add(marker);
                            mMarkerManager.addMarker(markers, MarkerManager.DELETE);
                            mMapView.postInvalidate();
                        } else {
                            toast("没有找到地址");
                        }
                    }

                    @Override
                    public void onFailure(String error) {
                        hideLoading();
                        toast(error);
                        LogUtils.e(TAG, "onFailure:" + error);
                    }
                });


            }
        });
        mBtnGeocoder2.setOnClickListener(v -> {
            showLoading();
            TianDiTuApi tianDiTuApi = TianDiTuApi.getInstance();
            //逆地理编码
            IGeoPoint mapCenter = mMapView.getMapCenter();
            tianDiTuApi.geocoderReverse(mapCenter.getLatitude(), mapCenter.getLongitude(), new Callback<ZAddress>() {
                @Override
                public void onSuccess(ZAddress data) {
                    hideLoading();
                    if (data != null) {
                        LogUtils.d(TAG, "GeocoderResult.result:" + GsonUtils.getDefault().toJson(data));
                    }
                }

                @Override
                public void onFailure(String error) {
                    hideLoading();
                    LogUtils.e(TAG, "onFailure:" + error);
                }
            });
        });
        mBtnGetArea.setOnClickListener(v -> {
            showLoading();
            TianDiTuApi tianDiTuApi = TianDiTuApi.getInstance();
            List<String> areaCode = new ArrayList<>();
            areaCode.add("156110000");
            areaCode.add("156130000");
            areaCode.add("156370000");
            areaCode.add("156510000");
            areaCode.add("156510100");
            areaCode.add("156310000");
            areaCode.add("156500000");
//            areaCode.add("156000000");
            mAreaIndex++;
            if (mAreaIndex >= areaCode.size()) {
                mAreaIndex = 0;
            }
            //行政区划
            tianDiTuApi.searchArea(areaCode.get(mAreaIndex), 1, true,  new Callback<AreaBoundary>() {
                @Override
                public void onSuccess(AreaBoundary data) {
                    hideLoading();
                    if (data != null) {
//                        LogUtils.d(TAG, "searchArea:" + GsonUtils.getDefault().toJson(data));
                        List<List<GeoPoint>> points = OsmdroidUtils.areaBoundaryToGeoPoints(data);
                        if (points != null) {
                            LogUtils.d(TAG, "行政区划边界个数:" + points.size());
                            int size = 0;
                            for (int i = 0; i < points.size(); i++) {
                                size += points.get(i).size();
                            }
                            LogUtils.d(TAG, "行政区划边界点数:" + size);

                            // 创建线实例
                            PolygonMask polygon = new PolygonMask(mMapView);
                            polygon.getOutlinePaint().setColor(0xFFFF00FF);
                            polygon.setMaskColor(0xFF6E84D6);
                            polygon.setDrawMask(true);
                            polygon.setHoles(points);
                            mPolygonMaskManager.setLimitMinZoom(false);
                            mPolygonMaskManager.setLimitBounds(true);
                            mPolygonMaskManager.setIsAnimated(true);
                            mPolygonMaskManager.setAnimationSpeed(1000L);
                            mPolygonMaskManager.set(polygon);
                        }
                        ZLatLng center = data.getCenter();
                        if (center != null) {
                            GeoPoint geoPoint = new GeoPoint(center.getLatitude(), center.getLongitude());
                            IMapController controller = mMapView.getController();
                            controller.setCenter(geoPoint);
                            mMapView.postInvalidate();
                        }
                    }

                }

                @Override
                public void onFailure(String error) {
                    hideLoading();
                    LogUtils.e(TAG, "onFailure:" + error);
                }
            });
        });
        //绘制线
        mBtnPolyline.setOnClickListener(v -> {
            LogUtils.d(TAG, "绘制线");
            // 点集合
            List<GeoPoint> pointList = new ArrayList<>();
            pointList.add(new GeoPoint(40.15, 108.01));
            pointList.add(new GeoPoint(33.47, 115.84));
            pointList.add(new GeoPoint(29.50, 109.73));
            // 创建线实例
            Polyline polyline = new Polyline(mMapView, true);
            // 设置点击图形，不弹出视图弹窗
//            polyline.setInfoWindow(null);
            // 设置线颜色
            polyline.getOutlinePaint().setColor(Color.RED);
            // 设置线宽度
            polyline.getOutlinePaint().setStrokeWidth(15);
            // 赋值
            polyline.setPoints(pointList);
            // 添加线
            mMapView.getOverlays().add(polyline);
            // 刷新
            mMapView.postInvalidate();


        });
        //绘制面
        mBtnPolygon.setOnClickListener(v -> {
            LogUtils.d(TAG, "绘制面");
            // 点集合
            // 创建线实例
            PolygonMask polygon = new PolygonMask(mMapView);
            List<List<GeoPoint>> rects = new ArrayList<>();
            List<GeoPoint> rect = new ArrayList<>();
            rect.add(new GeoPoint(63.55, 53.45));
            rect.add(new GeoPoint(63.55, 155.083333));
            rect.add(new GeoPoint(23.85, 155.083333));
            rect.add(new GeoPoint(23.85, 53.45));
            rects.add(rect);

            rect = new ArrayList<>();
            rect.add(new GeoPoint(13.55, 53.45));
            rect.add(new GeoPoint(13.55, 155.083333));
            rect.add(new GeoPoint(-3.85, 155.083333));
            rect.add(new GeoPoint(-3.85, 53.45));
            rects.add(rect);
            polygon.setHoles(rects);
            mPolygonMaskManager.set(polygon);

        });
//       new Thread(()->{
//          while (!isDestroyed()){
//              int size = overlayManager.size();
//              LogUtils.d(TAG, "overlay size:"+size);
//              for (int i = 0; i <size ; i++) {
//                  Overlay overlay = overlayManager.get(i);
//                  LogUtils.d(TAG, "overlay="+overlay.getClass().getSimpleName());
//              }
//              try {
//                  Thread.sleep(3000);
//              } catch (InterruptedException e) {
//                  throw new RuntimeException(e);
//              }
//          }
//       }).start();

    }

    private void search(int queryType) {
        showLoading();
        TianDiTuApi tianDiTuApi = TianDiTuApi.getInstance();
        //行政区划区域搜索服务
        SearchParams searchParams = new SearchParams();
        searchParams.setKeyWord("学校");
        if (queryType == SearchParams.QUERY_TYPE_AREA) {
            searchParams.setSpecify("中国");
        } else if (queryType == SearchParams.QUERY_TYPE_BOUND) {
            searchParams.setLevel((int) Math.round(mMapView.getZoomLevelDouble()));
            MapBound mapBound = mMapHelper.getMapBound();
            searchParams.setBound(mapBound);
        } else if (queryType == SearchParams.QUERY_TYPE_NEAR) {
//            searchParams.setLevel((int) Math.round(mMapView.getZoomLevelDouble()));
            IGeoPoint mapCenter = mMapView.getMapCenter();
            searchParams.setPointLonlat(mapCenter.getLongitude() + "," + mapCenter.getLatitude());
            searchParams.setQueryRadius(3000);
        }else if(queryType==SearchParams.QUERY_TYPE_NORMAL){
            searchParams.setLevel((int) Math.round(mMapView.getZoomLevelDouble()));
            MapBound mapBound = mMapHelper.getMapBound();
            searchParams.setBound(mapBound);
        }
        searchParams.setQueryType(queryType);
        searchParams.setStart(0);
        searchParams.setCount(30);
        searchParams.setShow(2);
        tianDiTuApi.search(searchParams, new Callback<SearchResult>() {
            @Override
            public void onSuccess(SearchResult data) {
                LogUtils.d(TAG, "onSuccess:" + GsonUtils.getDefault().toJson(data));
                addSearchResultMarker(data);
                hideLoading();
            }

            @Override
            public void onFailure(String error) {
                LogUtils.e(TAG, "onFailure:" + error);
                hideLoading();
            }
        });
    }


    private void addSearchResultMarker(SearchResult data) {
        if (data != null && data.isSuccess()) {
            List<Poi> pois = data.getPois();
            if (pois != null && !pois.isEmpty()) {
                List<Marker> markers = new ArrayList<>();
                for (Poi item : pois) {
                    MyMarker marker = new MyMarker(mMapView);
                    marker.setIcon(ContextCompat.getDrawable(this, R.drawable.icon_map_monitor_online));
                    marker.setAnchor(0, 0.5f);
                    marker.setPosition(new GeoPoint(item.getLatitude(), item.getLongitude()));
                    marker.setId(item.getAddress());
                    marker.setRelatedObject(item);
                    marker.setInfoWindow(new MyInfoWindow(mMapView));
                    marker.setOnMarkerClickListener((marker1, mapView) -> {
                        if (mShowInfoWindow != null && mShowInfoWindow != marker1.getInfoWindow() && mShowInfoWindow.isOpen()) {
                            mShowInfoWindow.close();
                        }
                        if (marker1.isInfoWindowShown()) {
                            marker1.closeInfoWindow();
                        } else {
                            marker1.showInfoWindow();
                            mShowInfoWindow = marker1.getInfoWindow();
                        }
                        return true;
                    });
                    //不移动到地图中间
                    marker.setPanToView(false);
                    markers.add(marker);
                }
                mMarkerManager.addMarker(markers, MarkerManager.DELETE);
                mMapView.postInvalidate();
            } else {
                toast("没有数据");
            }

        } else {
            toast("获取失败");
        }
    }

    private static class MyInfoWindow extends InfoWindow {


        public MyInfoWindow(MapView mapView) {
            super(R.layout.search_result_info_window, mapView);
        }

        @Override
        public void onOpen(Object item) {
            LogUtils.d(TAG, "item:" + item);
            View view = getView();
            TextView tvName = view.findViewById(R.id.tv_name);
            TextView tvAddress = view.findViewById(R.id.tv_address);
            Poi poi = null;
            if (item instanceof Marker marker) {
                Object relatedObject = marker.getRelatedObject();
                if (relatedObject instanceof Poi) {
                    poi = (Poi) relatedObject;
                }
            }
            if (poi != null) {
                tvName.setText(poi.getName());
                tvAddress.setText(poi.getAddress());
            }
            view.setOnClickListener(v -> ToastUtils.toastShort("点击InfoWindow"));
        }

        @Override
        public void onClose() {

        }
    }

    private void toast(String msg) {
        ToastUtils.toastShort(this, msg);
    }

    private Disposable mDisposableFirm;

    /**
     * 获取企业
     */
    private void loadFirms() {
        if (mDisposableFirm != null && !mDisposableFirm.isDisposed()) {
            LogUtils.d(TAG, "loadFirms:取消上个请求");
            mDisposableFirm.dispose();
        }
        showLoading();
        mDisposableFirm = Observable
                .create((ObservableOnSubscribe<List<Firm>>) emitter -> {
                    Random random = new SecureRandom();
                    try {
                        Thread.sleep(random.nextInt(200) + 100);
                    } catch (InterruptedException e) {

                    }
                    int count = random.nextInt(10000);
                    List<Firm> firms = new ArrayList<>();
                    for (int i = 0; i < 10000; i++) {
                        Firm firm = new Firm();
                        firm.setFirmName("测试企业" + i);
                        firm.setId("fid_" + i);
                        firm.setAddress("企业地址水电费水电费是的");
                        firm.setStatus(random.nextInt(3));
                        //3.85 53.55
                        firm.setLatitude(random.nextDouble() * 49 + 3.85);
                        //73.45 135.083333
                        firm.setLongitude(random.nextDouble() * 61 + 73.45);
                        firms.add(firm);
                    }

                    emitter.onNext(firms);
                    emitter.onComplete();

                })
                .compose(SchedulerUtils.apply())
                .subscribe(this::addMarker, throwable -> {
                    throwable.printStackTrace();
                    LogUtils.e(TAG, "loadFirms:" + throwable.getMessage());
                });
    }

    private static final double tolerance3 = 684_000;

    /**
     * 添加企业marker到地图上
     *
     * @param firms
     */
    private void addMarker(List<Firm> firms) {
        LogUtils.d(TAG, "抽稀前:" + firms.size());
        List<Firm> simplify = DouglasPeucker.reduceMarkers(firms, tolerance3);
        LogUtils.d(TAG, "抽稀后:" + simplify.size());


        List<Marker> markers = new ArrayList<>();
        MapBound mapBound = mMapHelper.getMapBound();
        for (Firm item : simplify) {
            GeoPoint geoPoint = new GeoPoint(item.getLatitude(), item.getLongitude());
            /*if (mapBound != null && !mMapHelper.isInMapBound(mapBound, geoPoint)) {
                continue;
            }*/
            MyMarker marker = new MyMarker(mMapView);
            marker.setAnchor(0.5f, 0.5f);
            int status = item.getStatus();
            if (status == Firm.ONLINE) {
                marker.setIcon(ContextCompat.getDrawable(this, R.drawable.icon_map_monitor_online));
            } else if (status == Firm.OFFLINE) {
                marker.setIcon(ContextCompat.getDrawable(this, R.drawable.icon_map_monitor_offline));
            } else {
                marker.setIcon(ContextCompat.getDrawable(this, R.drawable.icon_map_monitor_null));
            }
            marker.setOnMarkerClickListener(new Marker.OnMarkerClickListener() {
                @Override
                public boolean onMarkerClick(Marker marker, MapView mapView) {
                    LogUtils.d(TAG, "onMarkerClick:点击marker");
                    return true;
                }
            });
            marker.setPosition(geoPoint);
            marker.setId(item.getId());
            markers.add(marker);
        }
        long startTime = System.currentTimeMillis();
        mMarkerManager.addMarker(markers, MarkerManager.DELETE_KEEP);
        LogUtils.d(TAG, "耗时:" + (System.currentTimeMillis() - startTime) / 1000f);
        List<Marker> firm = mMarkerManager.getMarkers();
        LogUtils.d(TAG, "marker size:" + (firm != null ? firm.size() : 0));
        mMapView.postInvalidate();
        hideLoading();
    }


    public static int dpTopx(Context context, float dipValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }


    private void showLoading() {
        if (mProgress != null) {
            mProgress.setVisibility(View.VISIBLE);
        }
    }

    private void hideLoading() {
        if (mProgress != null) {
            mProgress.setVisibility(View.GONE);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        LogUtils.d(TAG, "onResume:isGpsOpen=" + Utils.isGpsOpen(this));
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mGpsLocationService.destroy();
    }
}